#include "oled_port.h"
#include "string.h"
#include "stm32f1xx_hal.h"
#include "spi.h"

#define  SCL_PORT   GPIOA
#define  SCL_PIN	GPIO_PIN_5
#define  SDA_PORT   GPIOA
#define	 SDA_PIN	GPIO_PIN_7 
#define  RES_PORT   GPIOB
#define  RES_PIN    GPIO_PIN_0
#define  DC_PORT    GPIOB
#define  DC_PIN     GPIO_PIN_1

#define OLED_CMD 	0
#define OLED_DATA 	1

static void OLED_RES_Set(void)
{
  HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_SET);
}
static void OLED_DC_Set(void)
{
  HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_SET);
}
static void OLED_RES_Clr(void)
{
  HAL_GPIO_WritePin(RES_PORT,RES_PIN,GPIO_PIN_RESET);
}
static void OLED_DC_Clr(void)
{
  HAL_GPIO_WritePin(DC_PORT,DC_PIN,GPIO_PIN_RESET);
}

// volatile uint8_t spi_tx_complete = 1;
// void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {
//     if (hspi->Instance == SPI1) {
//         spi_tx_complete = 1;
//     }
// }


static void OLED_WriteByte(uint8_t dat, uint8_t cORd)
{
    if(cORd) OLED_DC_Set();
    else OLED_DC_Clr();
    // uint32_t time_out = 0xFFFFFFFF;
    // while((spi_tx_complete == 0) && (time_out--)); //等待发送完成
    HAL_SPI_Transmit(&hspi1, &dat, 1, 100);
    OLED_DC_Set();
}

#include "stdio.h"
static void OLED_WriteByteArrayData(uint8_t * data_array,uint16_t len)
{
    OLED_DC_Set();
    // uint32_t time_out = 0xFFFFFFFF;
    // while((spi_tx_complete == 0) && (time_out--)); //等待发送完成
    // if(time_out != 0){HAL_SPI_Transmit_DMA(&hspi1,data_array,len);spi_tx_complete = 0;}
    HAL_SPI_Transmit(&hspi1, data_array, len, 1000);
}


void OLED_Init(void)
{   
    HAL_Delay(100);
    OLED_RES_Clr();
    HAL_Delay(300);
    OLED_RES_Set();

    OLED_WriteByte(0xAE,OLED_CMD);//--turn off oled panel
    OLED_WriteByte(OLED_LOW_COLUMN_ADDR,OLED_CMD);//---set low column address
    OLED_WriteByte(0x10,OLED_CMD);//---set high column address
    OLED_WriteByte(0x40,OLED_CMD);//--set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
    OLED_WriteByte(0x81,OLED_CMD);//--set contrast control register
    OLED_WriteByte(0xCF,OLED_CMD);// Set SEG Output Current Brightness
    OLED_WriteByte(0xA1,OLED_CMD);//--Set SEG/Column Mapping     0xa0左右反置 0xa1正常
    OLED_WriteByte(0xC8,OLED_CMD);//Set COM/Row Scan Direction   0xc0上下反置 0xc8正常
    OLED_WriteByte(0xA6,OLED_CMD);//--set normal display
    OLED_WriteByte(0xA8,OLED_CMD);//--set multiplex ratio(1 to 64)
    OLED_WriteByte(0x3f,OLED_CMD);//--1/64 duty
    OLED_WriteByte(0xD3,OLED_CMD);//-set display offset	Shift Mapping RAM Counter (0x00~0x3F)
    OLED_WriteByte(0x00,OLED_CMD);//-not offset
    OLED_WriteByte(0xd5,OLED_CMD);//--set display clock divide ratio/oscillator frequency
    OLED_WriteByte(0x80,OLED_CMD);//--set divide ratio, Set Clock as 100 Frames/Sec
    OLED_WriteByte(0xD9,OLED_CMD);//--set pre-charge period
    OLED_WriteByte(0xF1,OLED_CMD);//Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
    OLED_WriteByte(0xDA,OLED_CMD);//--set com pins hardware configuration
    OLED_WriteByte(0x12,OLED_CMD);
    OLED_WriteByte(0xDB,OLED_CMD);//--set vcomh
    OLED_WriteByte(0x40,OLED_CMD);//Set VCOM Deselect Level
    OLED_WriteByte(0x20,OLED_CMD);//-Set Page Addressing Mode (0x00/0x01/0x02)
    OLED_WriteByte(0x02,OLED_CMD);//
    OLED_WriteByte(0x8D,OLED_CMD);//--set Charge Pump enable/disable
    OLED_WriteByte(0x14,OLED_CMD);//--set(0x10) disable
    OLED_WriteByte(0xA4,OLED_CMD);// Disable Entire Display On (0xa4/0xa5)
    OLED_WriteByte(0xA6,OLED_CMD);// Disable Inverse Display On (0xa6/a7) 
    //OLED_SPIFill(0x00);
    OLED_WriteByte(0xAF,OLED_CMD);
}


void OLED_SendBuff(uint8_t buff[8][128])
{		    
	for(uint8_t i=0;i<8;i++)  
	{  
		OLED_WriteByte (0xb0+i,OLED_CMD);    //设置页地址（0~7）(b0-b7)
		OLED_WriteByte (OLED_LOW_COLUMN_ADDR,OLED_CMD);      //设置显示位置—列低地址
		OLED_WriteByte (0x10,OLED_CMD);      //设置显示位置—列高地址   
		OLED_WriteByteArrayData(buff[i],128); //写一页128个字符
	} //更新显示
}

//屏幕旋转180度
void OLED_DisplayTurn(uint8_t inverse)
{
	if(inverse==0)
		{
			OLED_WriteByte(0xC8,OLED_CMD);//正常显示
			OLED_WriteByte(0xA1,OLED_CMD);
		}
	if(inverse==1)
		{
			OLED_WriteByte(0xC0,OLED_CMD);//反转显示
			OLED_WriteByte(0xA0,OLED_CMD);
		}
}

#if (OLED_DRIVER == OLED_DRIVER_SSD1306)

#elif (OLED_DRIVER == OLED_DRIVER_SH1106)
//反显函数
void OLED_ColorTurn(uint8_t inverse)
{
	if(inverse==0)
		{
			OLED_WriteByte(0xA6,OLED_CMD);//正常显示
		}
	if(inverse==1)
		{
			OLED_WriteByte(0xA7,OLED_CMD);//反色显示
		}
}



#endif

